package org.admanager.mapping.plugin.diagram.providers;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.admanager.mapping.plugin.diagram.edit.parts.ComponentComponentCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentReferenceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentReferenceMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentServiceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ComponentServiceMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.CompositeCompositeCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.CompositeEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.CompositeMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.DocumentRootDocumentRootCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponent2EditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentPComponentCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentPInnerComponentCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentReference2EditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentReferenceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentService2EditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PComponentServiceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PCompositeEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PCompositePCompositeCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PReferenceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PServiceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.PatternPatternCompartmentEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ReferenceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ReferenceMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.RootMappingEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ServiceEditPart;
import org.admanager.mapping.plugin.diagram.edit.parts.ServiceMappingEditPart;
import org.admanager.mapping.plugin.diagram.part.Messages;
import org.admanager.mapping.plugin.diagram.part.SOADManagementMetamodelDiagramEditorPlugin;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.ui.services.modelingassistant.ModelingAssistantProvider;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;

/**
 * @generated
 */
public class SOADManagementMetamodelModelingAssistantProvider extends
		ModelingAssistantProvider {

	/**
	 * @generated
	 */
	public List getTypesForPopupBar(IAdaptable host) {
		IGraphicalEditPart editPart = (IGraphicalEditPart) host
				.getAdapter(IGraphicalEditPart.class);
		if (editPart instanceof RootMappingEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					8);
			types.add(SOADManagementMetamodelElementTypes.ComponentReferenceMapping_2010);
			types.add(SOADManagementMetamodelElementTypes.ComponentServiceMapping_2011);
			types.add(SOADManagementMetamodelElementTypes.CompositeMapping_2012);
			types.add(SOADManagementMetamodelElementTypes.ComponentMapping_2013);
			types.add(SOADManagementMetamodelElementTypes.ServiceMapping_2014);
			types.add(SOADManagementMetamodelElementTypes.ReferenceMapping_2015);
			types.add(SOADManagementMetamodelElementTypes.DocumentRoot_2016);
			types.add(SOADManagementMetamodelElementTypes.Pattern_2017);
			return types;
		}
		if (editPart instanceof DocumentRootDocumentRootCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					1);
			types.add(SOADManagementMetamodelElementTypes.Composite_3016);
			return types;
		}
		if (editPart instanceof CompositeCompositeCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(SOADManagementMetamodelElementTypes.Component_3011);
			types.add(SOADManagementMetamodelElementTypes.Service_3014);
			types.add(SOADManagementMetamodelElementTypes.Reference_3015);
			return types;
		}
		if (editPart instanceof ComponentComponentCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(SOADManagementMetamodelElementTypes.ComponentReference_3009);
			types.add(SOADManagementMetamodelElementTypes.ComponentService_3008);
			return types;
		}
		if (editPart instanceof PatternPatternCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(SOADManagementMetamodelElementTypes.PComponent_3017);
			types.add(SOADManagementMetamodelElementTypes.PComposite_3020);
			return types;
		}
		if (editPart instanceof PComponentPComponentCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(SOADManagementMetamodelElementTypes.PComponentService_3018);
			types.add(SOADManagementMetamodelElementTypes.PComponentReference_3019);
			return types;
		}
		if (editPart instanceof PCompositePCompositeCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					3);
			types.add(SOADManagementMetamodelElementTypes.PComponent_3021);
			types.add(SOADManagementMetamodelElementTypes.PService_3024);
			types.add(SOADManagementMetamodelElementTypes.PReference_3025);
			return types;
		}
		if (editPart instanceof PComponentPInnerComponentCompartmentEditPart) {
			ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/types = new ArrayList/*[org.eclipse.gmf.runtime.emf.type.core.IElementType]*/(
					2);
			types.add(SOADManagementMetamodelElementTypes.PComponentService_3022);
			types.add(SOADManagementMetamodelElementTypes.PComponentReference_3023);
			return types;
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnSource(IAdaptable source) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentReferenceMappingEditPart) {
			return ((ComponentReferenceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ComponentServiceMappingEditPart) {
			return ((ComponentServiceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof CompositeMappingEditPart) {
			return ((CompositeMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ServiceMappingEditPart) {
			return ((ServiceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		if (sourceEditPart instanceof ReferenceMappingEditPart) {
			return ((ReferenceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSource();
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnTarget(IAdaptable target) {
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (targetEditPart instanceof CompositeEditPart) {
			return ((CompositeEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ComponentEditPart) {
			return ((ComponentEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ComponentReferenceEditPart) {
			return ((ComponentReferenceEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ComponentServiceEditPart) {
			return ((ComponentServiceEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ServiceEditPart) {
			return ((ServiceEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof ReferenceEditPart) {
			return ((ReferenceEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentEditPart) {
			return ((PComponentEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentServiceEditPart) {
			return ((PComponentServiceEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentReferenceEditPart) {
			return ((PComponentReferenceEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PCompositeEditPart) {
			return ((PCompositeEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponent2EditPart) {
			return ((PComponent2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentService2EditPart) {
			return ((PComponentService2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PComponentReference2EditPart) {
			return ((PComponentReference2EditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PServiceEditPart) {
			return ((PServiceEditPart) targetEditPart).getMARelTypesOnTarget();
		}
		if (targetEditPart instanceof PReferenceEditPart) {
			return ((PReferenceEditPart) targetEditPart)
					.getMARelTypesOnTarget();
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getRelTypesOnSourceAndTarget(IAdaptable source,
			IAdaptable target) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentReferenceMappingEditPart) {
			return ((ComponentReferenceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ComponentServiceMappingEditPart) {
			return ((ComponentServiceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof CompositeMappingEditPart) {
			return ((CompositeMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ServiceMappingEditPart) {
			return ((ServiceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		if (sourceEditPart instanceof ReferenceMappingEditPart) {
			return ((ReferenceMappingEditPart) sourceEditPart)
					.getMARelTypesOnSourceAndTarget(targetEditPart);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getTypesForSource(IAdaptable target,
			IElementType relationshipType) {
		IGraphicalEditPart targetEditPart = (IGraphicalEditPart) target
				.getAdapter(IGraphicalEditPart.class);
		if (targetEditPart instanceof CompositeEditPart) {
			return ((CompositeEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ComponentEditPart) {
			return ((ComponentEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ComponentReferenceEditPart) {
			return ((ComponentReferenceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ComponentServiceEditPart) {
			return ((ComponentServiceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ServiceEditPart) {
			return ((ServiceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof ReferenceEditPart) {
			return ((ReferenceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentEditPart) {
			return ((PComponentEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentServiceEditPart) {
			return ((PComponentServiceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentReferenceEditPart) {
			return ((PComponentReferenceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PCompositeEditPart) {
			return ((PCompositeEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponent2EditPart) {
			return ((PComponent2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentService2EditPart) {
			return ((PComponentService2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PComponentReference2EditPart) {
			return ((PComponentReference2EditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PServiceEditPart) {
			return ((PServiceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		if (targetEditPart instanceof PReferenceEditPart) {
			return ((PReferenceEditPart) targetEditPart)
					.getMATypesForSource(relationshipType);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public List getTypesForTarget(IAdaptable source,
			IElementType relationshipType) {
		IGraphicalEditPart sourceEditPart = (IGraphicalEditPart) source
				.getAdapter(IGraphicalEditPart.class);
		if (sourceEditPart instanceof ComponentReferenceMappingEditPart) {
			return ((ComponentReferenceMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ComponentServiceMappingEditPart) {
			return ((ComponentServiceMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof CompositeMappingEditPart) {
			return ((CompositeMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ComponentMappingEditPart) {
			return ((ComponentMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ServiceMappingEditPart) {
			return ((ServiceMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		if (sourceEditPart instanceof ReferenceMappingEditPart) {
			return ((ReferenceMappingEditPart) sourceEditPart)
					.getMATypesForTarget(relationshipType);
		}
		return Collections.EMPTY_LIST;
	}

	/**
	 * @generated
	 */
	public EObject selectExistingElementForSource(IAdaptable target,
			IElementType relationshipType) {
		return selectExistingElement(target,
				getTypesForSource(target, relationshipType));
	}

	/**
	 * @generated
	 */
	public EObject selectExistingElementForTarget(IAdaptable source,
			IElementType relationshipType) {
		return selectExistingElement(source,
				getTypesForTarget(source, relationshipType));
	}

	/**
	 * @generated
	 */
	protected EObject selectExistingElement(IAdaptable host, Collection types) {
		if (types.isEmpty()) {
			return null;
		}
		IGraphicalEditPart editPart = (IGraphicalEditPart) host
				.getAdapter(IGraphicalEditPart.class);
		if (editPart == null) {
			return null;
		}
		Diagram diagram = (Diagram) editPart.getRoot().getContents().getModel();
		HashSet/*[org.eclipse.emf.ecore.EObject]*/elements = new HashSet/*[org.eclipse.emf.ecore.EObject]*/();
		for (Iterator/*[org.eclipse.emf.ecore.EObject]*/it = diagram
				.getElement().eAllContents(); it.hasNext();) {
			EObject element = (EObject) it.next();
			if (isApplicableElement(element, types)) {
				elements.add(element);
			}
		}
		if (elements.isEmpty()) {
			return null;
		}
		return selectElement((EObject[]) elements.toArray(new EObject[elements
				.size()]));
	}

	/**
	 * @generated
	 */
	protected boolean isApplicableElement(EObject element, Collection types) {
		IElementType type = ElementTypeRegistry.getInstance().getElementType(
				element);
		return types.contains(type);
	}

	/**
	 * @generated
	 */
	protected EObject selectElement(EObject[] elements) {
		Shell shell = Display.getCurrent().getActiveShell();
		ILabelProvider labelProvider = new AdapterFactoryLabelProvider(
				SOADManagementMetamodelDiagramEditorPlugin.getInstance()
						.getItemProvidersAdapterFactory());
		ElementListSelectionDialog dialog = new ElementListSelectionDialog(
				shell, labelProvider);
		dialog.setMessage(Messages.SOADManagementMetamodelModelingAssistantProviderMessage);
		dialog.setTitle(Messages.SOADManagementMetamodelModelingAssistantProviderTitle);
		dialog.setMultipleSelection(false);
		dialog.setElements(elements);
		EObject selected = null;
		if (dialog.open() == Window.OK) {
			selected = (EObject) dialog.getFirstResult();
		}
		return selected;
	}
}
